package com.hyt.it.ogt.ykcj.service.grade.impl;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import com.hyt.it.ogt.ykcj.common.core.domain.entity.SysUser;
import com.hyt.it.ogt.ykcj.common.enums.BizErrorCode;
import com.hyt.it.ogt.ykcj.common.exception.CustomException;
import com.hyt.it.ogt.ykcj.common.utils.SecurityUtils;
import com.hyt.it.ogt.ykcj.domain.grade.ExamineeGradeInfo;
import com.hyt.it.ogt.ykcj.domain.vo.ExamSubjectVo;
import com.hyt.it.ogt.ykcj.domain.vo.ImportGradeInfoVo;
import com.hyt.it.ogt.ykcj.mapper.exam.ExamSubjectInfoMapper;
import com.hyt.it.ogt.ykcj.mapper.exam.ExamSubjectNameConfigMapper;
import com.hyt.it.ogt.ykcj.mapper.grade.ExamineeGradeInfoMapper;
import com.hyt.it.ogt.ykcj.service.exam.IChangedExamInfoService;
import com.hyt.it.ogt.ykcj.service.grade.IExamineeGradeInfoService;
import com.hyt.it.ogt.ykcj.service.grade.ImportAbstractService;
import com.linuxense.javadbf.DBFReader;

/**
 * @Author chentb
 * @Date 2021/6/22 13:57
 */
@Service
public class ImportDbfGradeServiceImpl extends ImportAbstractService {

    private static final Logger log = LoggerFactory.getLogger(ImportDbfGradeServiceImpl.class);

    @Autowired
    private ExamineeGradeInfoMapper gradeInfoMapper;


    @Autowired
    private ExamSubjectNameConfigMapper subjectNameConfigMapper;

    @Autowired
    private IExamineeGradeInfoService gradeInfoService;

    @Autowired
    private ExamSubjectInfoMapper subjectInfoMapper;

    @Autowired
    IChangedExamInfoService changedExamInfoService;


    @Override
    @Transactional
    public List<ImportGradeInfoVo> importFile(MultipartFile file, String examId, String examNameConfigId, String examYear) {
        //  考试id是通过考试名称id、考试年份和考试时间查询出来的。
        log.info("导入成绩begin...文件类型为dbf文件");
        long startTime = System.currentTimeMillis();
        InputStream fis = null;
        List<ImportGradeInfoVo> list = new ArrayList<>();
        try {
            // 读取文件的输入流
            fis = file.getInputStream();
            // 根据输入流初始化一个DBFReader实例，用来读取DBF文件信息
            DBFReader reader = new DBFReader(fis);
            // 解决乱码
            reader.setCharactersetName("GBK");
            // 总条数
            int recordCount = reader.getRecordCount();
            if (recordCount == 0){
                throw new CustomException(BizErrorCode.COM_E0005);
            }

            // 调用DBFReader对实例方法得到path文件中字段的个数
            int fieldsCount = reader.getFieldCount();//获取字段数量
            int subjectNum = 0;
            // 获取所有的字段名称,并通过字段名称判断有多少个科目成绩
            String[] fieldName = new String[fieldsCount];
            for (int i = 0; i < fieldsCount; i++) {
                fieldName[i] = reader.getField(i).getName();
                if (fieldName[i].contains(PREFIX_KM)){
                    subjectNum ++;
                }
            }

            List<ExamSubjectVo> subjectVoList = subjectInfoMapper.selectExamSubjectInfoByExamId(examId);
            if (subjectNum != subjectVoList.size()){
                throw new CustomException(BizErrorCode.GRADE_E0009);
            }

            // 获取当前登录用户
            SysUser sysUser = SecurityUtils.getLoginUser().getUser();
            // 读取导入文件内容
            list = readImportFile(list,reader,subjectNum,fieldName,sysUser,examId,examNameConfigId,examYear);
        } catch (Exception e) {
            log.error("导入成绩信息出现异常",e);
            throw new CustomException("导入成绩信息出现异常");
        } finally {
            try {
                if(null != fis){
                    fis.close();
                    log.info("文件流关闭成功");
                }
            } catch (Exception e) {
                log.info("文件流关闭失败");
            }
        }
        long endTime = System.currentTimeMillis();
        log.info("导入成绩结束,共耗时{}秒",(endTime-startTime)/1000);
        return list;
    }

    private List<ImportGradeInfoVo> readImportFile(List<ImportGradeInfoVo> list, DBFReader reader, int subjectNum, String[] fieldName, SysUser sysUser, String examId, String examNameConfigId, String examYear) throws Exception{
        // 取出字段信息
        Object[] rowValues;
        // 数据是否校验通过
        boolean flag = true;
        //存放错误记录
        List<ImportGradeInfoVo> errorlist = new ArrayList<>();
        //记录行数
        int rowIndex = 0;
        // 考试考生成绩列表
        ExamineeGradeInfo examineeGradeInfo = new ExamineeGradeInfo();
        examineeGradeInfo.setExamId(examId);
        List<ExamineeGradeInfo> gradeInfoList = gradeInfoMapper.selectExamineeGradeInfoList(examineeGradeInfo);
        Map<String,ExamineeGradeInfo> gradeInfoMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(gradeInfoList)){
            gradeInfoMap = gradeInfoList.stream().collect(Collectors.toMap(ExamineeGradeInfo::getExamineeIdCode,gradeInfo->gradeInfo));
        }

        // 考试科目列表
        List<ExamSubjectVo> nameList = subjectInfoMapper.selectExamSubjectInfoByExamId(examId);
        Map<String,String> subjectNameMap = new HashMap<>();
        List<String> subjcetCodeList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(nameList)){
            subjectNameMap = nameList.stream().collect(Collectors.toMap(ExamSubjectVo::getSubjectNameCode,ExamSubjectVo::getSubjectId));
            subjcetCodeList = nameList.stream().map(ExamSubjectVo::getSubjectNameCode).collect(Collectors.toList());
        }
        // 一条条取出path文件中记录
        while ((rowValues = reader.nextRecord()) != null) {
            rowIndex++;
            ImportGradeInfoVo gradeInfoVo = new ImportGradeInfoVo();
            setGradeInfo(gradeInfoVo,subjcetCodeList,fieldName,rowValues,sysUser,examId,gradeInfoMap,subjectNameMap,examYear,rowIndex);
            if (!StringUtils.isEmpty(gradeInfoVo.getErrorMsg())){
                flag = false;
                errorlist.add(gradeInfoVo);
                continue;
            }
            list.add(gradeInfoVo);
        }
        if (!flag){
            return errorlist;
        }
        // list不为空则执行插入
        if (!CollectionUtils.isEmpty(list)){
           // gradeInfoService.insertGradeInfo(list);
            batchInsertGrade(list);
            // 插入需要变更的考试信息
            changedExamInfoService.addChangedExamInfo(examineeGradeInfo.getExamId());
        }
        return list;
    }

}
